/**
 * 
 */
package edu.uta.parsers;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import edu.uta.beans.DateBean;
import edu.uta.beans.ZipDataBean;


/**
 *  @author fall 2011 team5
 *
 */
public class XMLParser {

	public XMLParser()
	{
		
	}
	
	/*
	 * method getAQIByZipCode 
	 * input string zipcode
	 * returns arraylist of zipdatabean
	 */

	public static ArrayList<ZipDataBean> getAQIByZipCode(String zipcode)
	{
		//instantiate dataList
		ArrayList<ZipDataBean> dataList = new ArrayList<ZipDataBean>();
		try
		{
			//to parse the xml data using DOM parser
			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			//input zipcode is set in the url
			String urlforxml="http://ws1.airnowgateway.org/GatewayWebServiceREST/Gateway.svc/forecastbyzipcode?zipcode="+zipcode+"&date=&format=xml&key=440D5D7F-3DA9-45C7-8FD4-C4C371F4E47C";
			URL xmlUrl = new URL(urlforxml);
			InputStream in = xmlUrl.openStream();
			Document doc = docBuilder.parse(in);
			 //eliminate empty textual nodes.
			doc.getDocumentElement ().normalize ();
			
			//get all ForecastByZip elements
			NodeList forecastByZip = doc.getElementsByTagName("ForecastByZip");
			//iterate over each ForecastByZip element			
			for(int s=0; s<forecastByZip.getLength() ; s++)
			{
				//instantiate dataBean
				ZipDataBean dataBean = new ZipDataBean();
				//for a node within ForecastByZip element
				Node forecast = forecastByZip.item(s);
				//check if the node is an element
				if(forecast.getNodeType() == Node.ELEMENT_NODE)
				{
					//for an element get all nodes within by matching the tag name
					Element descriptionElement = (Element)forecast;
					NodeList forecastDateList = descriptionElement.getElementsByTagName("DateForecast");
					//get the first element that has date
					Element forecastDate = (Element)forecastDateList.item(0);
					//get all nodes within date element
					NodeList desc = forecastDate.getChildNodes();
					//from the first node get the value
					String forecastDateString=(desc.item(0)).getNodeValue().trim();
					//parse date and compare with system date to check if it is current
					//today attribute of zipdata bean is used to differentiate between
					//current AQI values and forecast AQI values
					DateBean date = parseDate(forecastDateString);
					if(compareDate(date))
					{
						//today is true is AQI data is current 
						dataBean.setToday(true);
					}
					//Splitting the extract date from date & time value in forecast date
					String dateArray[]=forecastDateString.split(" ");
					//set date in bean
					dataBean.setDateForecast(dateArray[0]);

					//extracting category name from xml
					NodeList categoryName = descriptionElement.getElementsByTagName("CategoryName");
					Element category = (Element)categoryName.item(0);
					NodeList pt = category.getChildNodes();			
					String cn=(pt.item(0)).getNodeValue().trim();
					dataBean.setCategoryName(cn);

					//extracting action day from xml
					NodeList actionDay = descriptionElement.getElementsByTagName("ActionDay");
					Element actionDayElement = (Element)actionDay.item(0);					
					NodeList actionDayList = actionDayElement.getChildNodes();			
					String ad=(actionDayList.item(0)).getNodeValue().trim();
					dataBean.setActionDay(ad);

					//extracting parameter name from xml
					NodeList parameters = descriptionElement.getElementsByTagName("ParameterName");
					Element parameter = (Element)parameters.item(0);					
					NodeList param = parameter.getChildNodes();			
					String parameterString =(param.item(0)).getNodeValue().trim();
					dataBean.setParameterName(parameterString);

					//extracting reporting area from xml
					NodeList reportingAreaList = descriptionElement.getElementsByTagName("ReportingArea");
					Element area = (Element)reportingAreaList.item(0);					
					NodeList areaList = area.getChildNodes();			
					String reportingArea=(areaList.item(0)).getNodeValue().trim();
					dataBean.setReportingArea(reportingArea);
					
					//extracting AQI
					NodeList AQIList = descriptionElement.getElementsByTagName("AQI");
					Element aqi = (Element)AQIList.item(0);					
					NodeList aqiList = aqi.getChildNodes();			
					String aqiValue=(aqiList.item(0)).getNodeValue().trim();
					//when no aqi data is available set AQI as empty
					if(aqiValue.equals("-1")){
						aqiValue="";
					}
					dataBean.setAQI(aqiValue);
				}
				//add bean to the arraylist
				dataList.add(dataBean);
			}//end for



		}
		catch (SAXParseException err) 
		{
			/*System.out.println ("** Parsing error" + ", line "
					+ err.getLineNumber () + ", uri " + err.getSystemId ());
			System.out.println(" " + err.getMessage ());
*/
		}
		catch (SAXException e)
		{
			Exception x = e.getException ();
			((x == null) ? e : x).printStackTrace ();

		}
		catch (Throwable t)
		{
			t.printStackTrace ();
		}
		
		return dataList;
	}
	//check if date is today's date
	private static boolean compareDate(DateBean date) {
		Calendar calendar = Calendar.getInstance();
		int day = calendar.get(Calendar.DATE);
		boolean today=false;
		if(day== date.getDay())
		{
			today= true;
		}

		return today;
	}

//split date string and return DateBean that is used for comparison of dates

	private static DateBean parseDate(String forecastDate) {
		// TODO Auto-generated method stub
		DateBean date= new DateBean();
		String dateTimeString[] = forecastDate.split(" ");
		String dateString[]=dateTimeString[0].split("/");
		if(dateString.length==3)
		{
			try
			{
				int month = Integer.parseInt(dateString[0]);
				int day= Integer.parseInt(dateString[1]);
				int year = Integer.parseInt(dateString[2]);
				date = new DateBean(month,day,year);

			}
			catch(NumberFormatException nfe)
			{
				nfe.printStackTrace();

			}

		}
		return date;

	}
}
